const DEFAULT_CONFIG = {
  v: '1.4.0',
  hostAndPath: 'api.map.baidu.com/api',
  key: 'f97efc35164149d0c0f299e7a8adb3d2',
  callback: '__bmap_init_callback',
  useBMapUI: false
};

let mainPromise = null
let bmapuiPromise = null
let bmapuiInited = false
export default class APILoader {
  constructor({ key, useBMapUI, version, protocol }) {
    this.config = { ...DEFAULT_CONFIG, useBMapUI, protocol }
    if (typeof window !== 'undefined') {
      if (key) {
        this.config.key = key
      } else if ('bmapkey' in window) {
        this.config.key = window.bmapkey
      }
    }
    if (version) {
      this.config.v = version
    }
    this.protocol = protocol || window.location.protocol;
    if (this.protocol.indexOf(':') === -1) {
      this.protocol += ':'
    }
  }

  getScriptSrc(cfg) {
    return `${this.protocol}//${cfg.hostAndPath}?v=${cfg.v}&ak=${cfg.key}&callback=${cfg.callback}`
  }

  buildScriptTag(src) {
    const script = document.createElement('script');
    script.type = 'text/javascript';
    script.async = true;
    script.defer = true;
    script.src = src;
    return script;
  }

  getBmapuiPromise() {
    const script = this.buildScriptTag(`${this.protocol}//webapi.amap.com/ui/1.0/main-async.js`)
    const p = new Promise(resolve => {
      script.onload = () => {
        resolve()
      }
    })
    document.body.appendChild(script)
    return p
  }

  getMainPromise() {
    const script = this.buildScriptTag(this.getScriptSrc(this.config));
    const p = new Promise(resolve => {
      window[this.config.callback] = () => {
        resolve();
        delete window[this.config.callback]
      }
    })
    document.body.appendChild(script)
    return p
  }

  load() {
    if (typeof window === 'undefined') {
      return null
    }
    const { useBMapUI } = this.config
    mainPromise = mainPromise || this.getMainPromise()
    if (useBMapUI) {
      bmapuiPromise = bmapuiPromise || this.getBmapuiPromise()
    }
    return new Promise(resolve => {
      mainPromise.then(() => {
        if (useBMapUI && bmapuiPromise) {
          bmapuiPromise.then(() => {
            if (window.initBMapUI && !bmapuiInited) {
              window.initBMapUI()
              if (typeof useBMapUI === 'function') {
                useBMapUI()
              }
              bmapuiInited = true
            }
            resolve()
          })
        } else {
          resolve()
        }
      })
    })
  }
}
